import binascii
import json
import socket
import logging
import requests
import select
import redis
from data_analysis import  data_analysis_hx100
import datetime
# log日志
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 内存
redis = redis.Redis(host='127.0.0.1', port=6379,db=0,password='jizhi@123')
# 数据推送
def push(code):
    # headers = {
    #     "Content-Type": "application/json; charset=UTF-8",
    #     "Referer": "http://jinbao.pinduoduo.com/index?page=5",
    #     "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36",
    # }
    # url = "http://127.0.0.1:5003/device/pass_by"
    # pyload = {"code": code}
    # logging.debug("url:%s"%url)
    # response = requests.post(url, data=json.dumps(pyload), headers=headers,timeout=5).text
    # logging.debug("response:%s"%response)
    data_analysis_hx100.hx100code(code)
# 数据处理
def recvData(connections,fd,epoll,addresses):

    # 从激活 fd 上接收
    recvData = connections[fd].recv(1024)
    logging.debug("%s---recv event---"%str(addresses[fd]))
    if len(recvData)>0:

        logging.debug('recv:%s'%recvData)
        data = binascii.b2a_hex(recvData)
        logging.debug('b2a_hex:%s'%data)
        data = data.decode(encoding ='utf-8',errors = 'strict')
        logging.debug('utf-8:%s'%data)
        if '7a7a' in data or '7b7b7b' in data:
            # 推送
            try:
                if '7a7a' in data:
                    number = data[0:14]
                    redisfd = redis.get(str(number))
                    if redisfd is None:
                        redis.set(number,fd)
                    else:
                        if int(redisfd) != int(fd):
                            connections.pop(int(redisfd))
                    redis.set(number,fd)
                response = push(data)
                content = "c8"
                connections[fd].send(binascii.a2b_hex(content))
            except BaseException as e:
                logging.debug('目标服务器异常！！！%s'%e)
        else:
            epoll.unregister(fd)
            connections[fd].close()
            connections.pop(fd)
            logging.debug('%s---data in wrong format---'%str(addresses[fd]))
    else:
        epoll.unregister(fd)
        connections[fd].close()
        connections.pop(fd)
        logging.debug('connections:%s'%connections)
        logging.debug('%s---nodata offline---'%str(addresses[fd]))

def main():
    # 创建套接字
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    # 设置可以重复使用绑定的信息
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

    # 绑定本机信息
    s.bind(("",8230))

    # 变为被动
    s.listen(10)
    # 非堵塞开启
    # s.setblocking(0)
    # 创建一个epoll对象
    epoll=select.epoll()

    # 测试，用来打印套接字对应的文件描述符
    # print s.fileno()
    # print select.EPOLLIN|select.EPOLLET

    # 注册事件到epoll中
    # epoll.register(fd[, eventmask])
    # 注意，如果fd已经注册过，则会发生异常
    # 将创建的套接字添加到epoll的事件监听中
    epoll.register(s.fileno(),select.EPOLLIN|select.EPOLLET)
    connections = {}
    addresses = {}
    # 循环等待客户端的到来或者对方发送数据
    while True:
        # epoll 进行 fd 扫描的地方 -- 未指定超时时间则为阻塞等待
        epoll_list=epoll.poll()
        logging.debug('recv event: {0}'.format(epoll_list))
        # 对事件进行判断
        for fd,events in epoll_list:

            # print fd
            # print events

            # 如果是socket创建的套接字被激活
            if fd == s.fileno():
                conn,addr=s.accept()
                logging.debug('Welcome new client connection%s'%str(addr))
                # 将 conn 和 addr 信息分别保存起来
                connections[conn.fileno()] = conn
                addresses[conn.fileno()] = addr
                logging.debug('connections:%s'%connections)
                # 打开tcpSO_KEEPALIVE选项
                #conn.setsockopt(socket.SOL_SOCKET,socket.SO_KEEPALIVE,True)
                #conn.ioctl(socket.SIO_KEEPALIVE_VALS,(1,20*1000,10*1000))
                # 向 epoll 中注册 连接 socket 的 可读 事件
                epoll.register(conn.fileno(), select.EPOLLIN | select.EPOLLET | select.EPOLLRDHUP | select.EPOLLHUP | select.EPOLLERR)

            elif events & select.EPOLLHUP:
                epoll.unregister(fd)
                connections[fd].close()
                connections.pop(fd)
                logging.debug('connections:%s'%connections)
                logging.debug('%s--- EPOLLHUP offline---'%str(addresses[fd]))

            elif events & select.EPOLLRDHUP:
                try:
                    epoll.unregister(fd)
                    connections[fd].close()
                    connections.pop(fd)
                    logging.debug('connections:%s'%connections)
                    logging.debug('%s--- EPOLLRDHUP offline---'%str(addresses[fd]))
                except BaseException as e:
                    logging.debug('EPOLLRDHUP_BaseException:%s'%e)
            elif events & select.EPOLLIN:
                recvData(connections,fd,epoll,addresses)
            else:
                epoll.unregister(fd)
                connections[fd].close()
                connections.pop(fd)
                logging.debug('connections:%s'%connections)
                logging.debug("%s---other error offline---"%str(addresses[fd]))

if __name__ == '__main__':
    main()
